﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LogisticDatabase;
using LogisticDatabase.Models;
using LogisticSimulator.Models;

namespace LogisticSimulator.Controllers
{
    public class OrderController : Controller
    {
        //
        // GET: /Order/

        IDataAccess<Order> orderDataAccess;
        IDataAccess<Product> productDataAccess;
        IDataAccess<Factory> factoryDataAccess;
        IWarhouseDataAccess warehouseDataAccess;



        public OrderController(IDataAccess<Order> orderDataAccess, IDataAccess<Product> productDataAccess,
            IDataAccess<Factory> factoryDataAccess, IWarhouseDataAccess warehouseDataAccess)
        {
            this.orderDataAccess = orderDataAccess;
            this.productDataAccess = productDataAccess;
            this.factoryDataAccess = factoryDataAccess;
            this.warehouseDataAccess = warehouseDataAccess;
        }

        public ActionResult Index()
        {
            ViewBag.Type = "Order";
            ViewBag.Operation = "Index";
            return RedirectToAction("List");
        }

        [HttpGet]
        public ActionResult Create()
        {

            ViewBag.Type = "Order";
            ViewBag.Operation = "Create";

            return View();
        
        }


        [HttpGet]
        public ActionResult List()
        {

            ViewBag.Type = "Order";
            ViewBag.Operation = "List";

            ViewBag.Factories = this.factoryDataAccess.listAll(); 

            return View();

        }


        /// <summary>
        /// Get factory list for ajax request
        /// </summary>
        /// <returns>List of factories in JSON</returns>

        [HttpPost]
        [ActionName("getFactories")]
        public JsonResult GetFactories()
        {
            List<Factory> factories = factoryDataAccess.listAll().ToList();

            return Json(factories);

        }

        /// <summary>
        /// Order state modification for ajax request
        /// </summary>
        /// <param name="id">Order id  </param>
        /// <param name="newState">New state in Text form</param>
        /// <returns></returns>

        [HttpPost]
        [ActionName("setOrderState")]
        public JsonResult SetOrderState(int id, string newState)
        {

            Order order = orderDataAccess.listAll().Where(t => t.Id == id).SingleOrDefault();
            order.State = Order.StringToOrderState(newState);

            orderDataAccess.edit(order);

            return Json(true);

        }

        
        /// <summary>
        /// Get order list from the database filter by factor id
        /// </summary>
        /// <param name="factoryId">Factory id, for which want know the orders</param>
        /// <returns></returns>

        [HttpPost]
        [ActionName("getOrders")]
        public JsonResult GetOrders(int factoryId)
        {
            List<Order> orders = orderDataAccess.listAll().ToList();

            List<OrderList> returnOrders = orderDataAccess.listAll()
                .Where(t=>t.Product.Factory.Id == factoryId )
                .Select(t => new OrderList
            {
                Id = t.Id,
                Producer = t.CustomerName,
                Product = t.Product.Name,
                Quantity = t.Quanity,
                Date = t.Date.ToString("yyyy.MM.dd."),
                State = t.StateText
                
            }).ToList();



            return Json(returnOrders);
            
            
            

        }

        /// <summary>
        /// Getting information, how much are from given product in the warehouse
        /// </summary>
        /// <param name="productId">Id of the given product</param>
        /// <returns></returns>

        [HttpPost]
        [ActionName("getProductsAvailabelity")]
        public JsonResult GetProductsAvailabelity(int productId)
        {
            var warehouseList = warehouseDataAccess.listAll();

            Product findProduct = null;

            foreach(var warehouse in warehouseList) 
            {
                findProduct = warehouse.products.Where(t => t.Id == productId).SingleOrDefault();

                if(findProduct!=null)
                {
                    break;
                }
                
            }

            if (findProduct != null)
            {

                return Json(findProduct.Capacity);
            }

            return Json(0);
        }


        /// <summary>
        /// Get products list from a given factory by factory name
        /// </summary>
        /// <param name="factoryName"></param>
        /// <returns></returns>

        [HttpPost]
        [ActionName("getProductsForFactory")]
        public JsonResult GetProductsForFactory(string factoryName)
        {
            List<Product> products = productDataAccess.listAll().Where(t => t.Factory.Name == factoryName).ToList();

            return Json(products);

        }

        /// <summary>
        /// Adding order to database by OrderCreate viewmodell.
        /// </summary>
        /// <param name="order">Contain the next information of the orders:
        /// selected product id and quantity. This function check also the accesible capacity for product
        /// in warehouse and compute based on this information.
        /// </param>
        /// <returns></returns>

        [HttpPost]
        [ActionName("addOrder")]
        public JsonResult AddOrder(OrderCreate order)
        {
            //List<Product> products = productDataAccess.listAll().Where(t => t.Factory.Name == factoryName).ToList();

            //check the warehouse capacity

            var warehouseList = warehouseDataAccess.listAll();

            Product findProduct = null;

            Warehouse findWarehouse = null;

            foreach (Warehouse  warehouse in warehouseList)
            {
                findProduct = warehouse.products
                    .Where(t => t.Id == order.SelectedProduct)
                    .SingleOrDefault();

                if (findProduct != null)
                {
                    findWarehouse  = warehouse;
                    break;
                }

            }

            int capacity;

            if (findProduct != null)
            {

                capacity = findProduct.Capacity;
            }

            else
            {
                capacity = 0;
            }

            int remainCapacity = 0;

            OrderState newState = OrderState.ACCEPTED;

            if(order.Quantity<=capacity)
            {
                newState = OrderState.TRANSPORT;

                remainCapacity = capacity - order.Quantity;
            }
            else
            {
                remainCapacity = 0;
            }


            Order newOrder = new Order
            {
                CustomerName = "Jani"
                ,
                Date = DateTime.Now
                ,
                State = newState
                ,
                Product = new Product { Id = order.SelectedProduct }
                ,
                Quanity = order.Quantity
            };

            orderDataAccess.add(newOrder);

            Warehouse capacityWarehouse = 
                new Warehouse {
                    Id = findWarehouse.Id,
                    products = new List<Product>{ 
                        new Product { Id = order.SelectedProduct, Capacity = remainCapacity}
                    }
                };

            warehouseDataAccess.updateProductCapacity(capacityWarehouse);

            return Json(true);

        }


	}
}